home *** CD-ROM | disk | FTP | other *** search
/ Macwelt 1 / Macwelt DVD 1.toast / Web-Publishing / HTML-Editoren / Alpha ƒ / Tcl / SystemCode / CorePackages / modeCreationAssistant.tcl < prev    next >
Encoding:
Text File  |  2000-11-06  |  14.3 KB  |  364 lines

  1. ## -*-Tcl-*-
  2.  # ###################################################################
  3.  #  AlphaTcl - core Tcl engine
  4.  # 
  5.  #  FILE: "modeCreationAssistant.tcl"
  6.  #                                    created: 02/29/2000 {09:40:40 AM} 
  7.  #                                last update: 11/06/2000 {21:03:48 PM} 
  8.  #  Author: Vince Darley
  9.  #  E-mail: vince@santafe.edu
  10.  #    mail: 317 Paseo de Peralta, Santa Fe, NM 87501
  11.  #     www: <http://www.santafe.edu/~vince/>
  12.  #  
  13.  # Copyright (c) 2000 Vince Darley, all rights reserved
  14.  # 
  15.  # Version 0.1.1 : extensions, simple menu, helper app, keywords,
  16.  # comment characters. wordWrap, funcExpr/parseExpr preferences.
  17.  # 
  18.  # I probably won't do much more work on this, so if you'd like
  19.  # to help, please do so.  Send your contributions via the Alpha-D
  20.  # mailing list for discussion.
  21.  # ###################################################################
  22.  ##
  23.  
  24. namespace eval modeAssistant {}
  25.  
  26. proc createNewMode {} {
  27.     modeAssistant
  28. }
  29.  
  30. ## 
  31.  # -------------------------------------------------------------------------
  32.  # 
  33.  # "modeAssistant" --
  34.  # 
  35.  # -------------------------------------------------------------------------
  36.  ##
  37. proc modeAssistant {} {
  38.     global modeAssistant
  39.     # We don't clear old values, in case the user cancelled and is
  40.     # trying again
  41.     ensureset modeAssistant(name) ""
  42.     ensureset modeAssistant(extensions) ""
  43.     ensureset modeAssistant(menuname) ""
  44.     ensureset modeAssistant(addHelper) 0
  45.     ensureset modeAssistant(helperApplication) "<no current helper>"
  46.     ensureset modeAssistant(helperName) ""
  47.     ensureset modeAssistant(switchhelper) 0
  48.     ensureset modeAssistant(sendtohelper) 0
  49.     ensureset modeAssistant(keywords) ""
  50.     ensureset modeAssistant(comments) ""
  51.     ensureset modeAssistant(multicommentprefix) ""
  52.     ensureset modeAssistant(multicommentsuffix) ""
  53.     ensureset modeAssistant(wordWrap) 0
  54.     ensureset modeAssistant(funcExpr) ""
  55.     ensureset modeAssistant(parseExpr) ""
  56.  
  57.     foreach page {
  58.     welcome modeMenu keywords comments wrapAndMark create
  59.     } {
  60.     modeAssistant::$page
  61.     }
  62. }
  63.  
  64. proc modeAssistant::start {title yy} {
  65.     upvar $yy y
  66.     if {[info tclversion] < 8.0} {
  67.     return [dialog::text $title 10 y 100]
  68.     } else {
  69.     return [list -T $title]
  70.     }
  71. }
  72.  
  73. proc modeAssistant::welcome {} {
  74.     global modeAssistant
  75.     set y 20
  76.     set dialog [modeAssistant::start "Mode creation assistant" y]
  77.     eval lappend dialog [dialog::text \
  78.       "Welcome to the Mode creation assistant.  This assistant will guide\
  79.       you through a few screens to create a new mode for Alpha and Alphatk."\
  80.       10 y 60]
  81.  
  82.     eval lappend dialog \
  83.       [dialog::text "Please enter the name for the mode.  This must be\
  84.       1-4 characters long, and may not contain any spaces:" 20 y 60] \
  85.       [dialog::edit $modeAssistant(name) 30 y 5] \
  86.       [dialog::text "Please enter the usual file patterns used for\
  87.       this mode, separated by spaces.  For example 'C' mode uses\
  88.       '*.c *.h'.  Extensions are case-sensitive, so you may wish to\
  89.       enter '*.ext *.EXT', for instance.  Whenever Alpha encounters a file\
  90.       with these extensions/patterns, it will automatically use your mode.\
  91.       You may enter as many such patterns as you\
  92.       like:" 20 y 60] \
  93.       [dialog::edit $modeAssistant(extensions) 30 y 20]
  94.         
  95.     incr y 20
  96.     
  97.     eval lappend dialog [dialog::button "Continue" 10 y "Cancel" 90 y] 
  98.     set res [eval dialog -w 440 -h $y $dialog]
  99.     
  100.     if {[lindex $res end]} {
  101.     error "Cancelled!"
  102.     }
  103.     set modeAssistant(name) [lindex $res 0]
  104.     set modeAssistant(extensions) [lindex $res 1]
  105. }
  106.  
  107. proc modeAssistant::modeMenu {} {
  108.     global modeAssistant
  109.     while {1} {
  110.     set y 20
  111.     set dialog [modeAssistant::start "Mode creation assistant - step 2" y]
  112.     eval lappend dialog [dialog::text \
  113.       "Many modes have their own special menu associated with them.\
  114.       Whenever you are using the mode, that menu is automatically\
  115.       placed in the menu bar.  It usually contains commands for two\
  116.       main purposes: commands very specific to editing in that mode,\
  117.       or commands to interact with one or more applications which\
  118.       understand the kind of files you are editing.  For example\
  119.       when editing .html files, it is convenient to have a menu\
  120.       containing commands to send the current .html window to your\
  121.       web browser." 10 y 100]
  122.     incr y 10
  123.     eval lappend dialog [dialog::text "If you would like to create\
  124.       a menu specific to this mode, please enter a short name for the\
  125.       menu (for instructions on using an icon as a name, please ask on\
  126.       the Alpha-D mailing list)" 20 y 80]
  127.     eval lappend dialog \
  128.       [dialog::textedit "Menu name:" $modeAssistant(menuname) 20 y 8] \
  129.       [dialog::checkbox "Add a helper application" \
  130.       $modeAssistant(addHelper) 20 y] \
  131.       [dialog::textedit "Short name for app:" $modeAssistant(helperName) 50 y 8] \
  132.       [dialog::button "Select helper application:" 50 y] \
  133.       [dialog::text $modeAssistant(helperApplication) 50 y] \
  134.       [dialog::checkbox "Add a menu command to switch to the helper" \
  135.       $modeAssistant(switchhelper) 50 y] \
  136.       [dialog::checkbox "Add a menu command to send the window to the helper" \
  137.       $modeAssistant(sendtohelper) 50 y]
  138.     
  139.     incr y 20
  140.     
  141.     eval lappend dialog [dialog::button "Continue" 10 y "Cancel" 90 y] 
  142.     
  143.     set res [eval dialog -w 640 -h $y $dialog]
  144.     if {[lindex $res end]} {
  145.         error "Cancelled!"
  146.     }
  147.     set modeAssistant(menuname) [lindex $res 0]
  148.     set modeAssistant(addHelper) [lindex $res 1]
  149.     set modeAssistant(helperName) [lindex $res 2]
  150.     set modeAssistant(switchhelper) [lindex $res 4]
  151.     set modeAssistant(sendtohelper) [lindex $res 5]
  152.     if {[lindex $res 3]} {
  153.         # pick helper button
  154.         set modeAssistant(helperApplication) [dialog::findAnyApp]
  155.     } else {
  156.         # Continue
  157.         break
  158.     }
  159.     }
  160.     
  161. }
  162.  
  163. proc modeAssistant::keywords {} {
  164.     global modeAssistant
  165.     set y 20
  166.     set dialog [modeAssistant::start "Mode creation assistant - step 3" y]
  167.     eval lappend dialog [dialog::text \
  168.       "Most modes have particular keywords which should be coloured\
  169.       differently.  Please enter this mode's keywords below."\
  170.       10 y 100]
  171.     incr y 10
  172.     eval lappend dialog \
  173.       [dialog::edit $modeAssistant(keywords) 20 y 40 10]
  174.     incr y 20
  175.     eval lappend dialog [dialog::button "Continue" 10 y "Cancel" 90 y] 
  176.     set res [eval dialog -w 640 -h $y $dialog]
  177.     if {[lindex $res end]} {
  178.     error "Cancelled!"
  179.     }
  180.     set modeAssistant(keywords) [lindex $res 0]
  181. }
  182.  
  183. proc modeAssistant::comments {} {
  184.     global modeAssistant
  185.     set y 20
  186.     set dialog [modeAssistant::start "Mode creation assistant - step 4" y]
  187.     eval lappend dialog [dialog::text \
  188.       "Most modes have particular codes used to signify\
  189.       a comment.  For example C++ and Java have '//' for a\
  190.       single line comment, and '/*','*/' for multi-line comments.\
  191.       Please enter this mode's comment characters below.  If the mode\
  192.       doesn't have multi-line comments, leave that section blank."\
  193.       10 y 100]
  194.     incr y 10
  195.     eval lappend dialog \
  196.       [dialog::textedit "Comment prefix:" $modeAssistant(comments) 20 y 4]\
  197.       [dialog::textedit "Multi-line prefix:" $modeAssistant(multicommentprefix) 20 y 4]\
  198.       [dialog::textedit "Multi-line suffix:" $modeAssistant(multicommentsuffix) 20 y 4]
  199.     incr y 20
  200.     eval lappend dialog [dialog::button "Continue" 10 y "Cancel" 90 y] 
  201.     set res [eval dialog -w 640 -h $y $dialog]
  202.     if {[lindex $res end]} {
  203.     error "Cancelled!"
  204.     }
  205.     set modeAssistant(comments) [lindex $res 0]
  206.     set modeAssistant(multicommentprefix) [lindex $res 1]
  207.     set modeAssistant(multicommentsuffix) [lindex $res 2]
  208. }
  209.  
  210. proc modeAssistant::wrapAndMark {} {
  211.     global modeAssistant
  212.     set y 20
  213.     set dialog [modeAssistant::start "Mode creation assistant - step 5" y]
  214.     eval lappend dialog [dialog::text \
  215.       "For 'textual' modes it is convenient to have Alpha wrap text as\
  216.       you type, so that no lines are excessively long.  For 'programming'\
  217.       modes, such automatic wrapping is usually undesireable.  Would you\
  218.       like your mode to have automatic wrapping? (It can be overridden later)"\
  219.       10 y 100]
  220.     eval lappend dialog \
  221.       [dialog::checkbox "Automatic word wrapping" $modeAssistant(wordWrap) 20 y]
  222.     incr y 10
  223.     eval lappend dialog [dialog::text \
  224.       "Alpha provides a 'funcs' menus which is generated by\
  225.       scanning documents for function names/section headings/etc.  The menu\
  226.       can then be used to jump to the location of the stored functions/headings.\
  227.       To do this for your mode, Alpha requires two regular expressions, one which\
  228.       will match a pattern containing something which needs marking, and the other\
  229.       which will take the matched text and extract, or parse, as the first bracketed '()'\
  230.       expression, the name of the item (i.e. the section/function name).  If\
  231.       you need help with this, please ask on the Alpha-D mailing list (you may leave\
  232.       them blank)."\
  233.       10 y 100]
  234.     eval lappend dialog [dialog::textedit "Function expression:"\
  235.       $modeAssistant(funcExpr) 20 y 50]
  236.     eval lappend dialog [dialog::textedit "Parse expression:"\
  237.       $modeAssistant(parseExpr) 20 y 50]
  238.     incr y 20
  239.     eval lappend dialog [dialog::button "Continue" 10 y "Cancel" 90 y] 
  240.     set res [eval dialog -w 640 -h $y $dialog]
  241.     if {[lindex $res end]} {
  242.     error "Cancelled!"
  243.     }
  244.     set modeAssistant(wordWrap) [lindex $res 0]
  245.     set modeAssistant(funcExpr) [lindex $res 1]
  246.     set modeAssistant(parseExpr) [lindex $res 2]
  247. }
  248.  
  249.  
  250. proc modeAssistant::create {} {
  251.     global modeAssistant
  252.     append t "# Automatically created by mode assistant\n#\n"
  253.     append t "# Mode: $modeAssistant(name)\n\n\n"
  254.  
  255.     if {[string length $modeAssistant(helperName)]} {
  256.     set appName "[string toupper [string index $modeAssistant(helperName) 0]][string range $modeAssistant(helperName) 1 end]"
  257.     set sigName "[string tolower $modeAssistant(helperName)]Sig"
  258.     set sig [getFileSig $modeAssistant(helperApplication)]
  259.     }
  260.     
  261.     append t "# Mode declaration.\n"
  262.     append t "#  first two items are: name version\n"
  263.     append t "#  then 'source' means source this file when we first use the mode\n"
  264.     append t "#  then we list the extensions, and any features active by default\n"
  265.     append t "alpha::mode [list $modeAssistant(name)] 0.1 source\
  266.       [list $modeAssistant(extensions)]"
  267.     
  268.     if {[string length $modeAssistant(menuname)]} {
  269.     append t " $modeAssistant(name)Menu"
  270.     } else {
  271.     append t " {}"
  272.     }
  273.     
  274.     append t " \{\n    \# Script to execute at Alpha startup\n"
  275.     if {[string length $modeAssistant(menuname)]} {
  276.     append t "    addMenu $modeAssistant(name)Menu $modeAssistant(menuname)\n"
  277.     if {[string length $modeAssistant(helperName)]} {
  278.         append t "    ensureset $sigName [list $sig]\n" 
  279.     }
  280.     }
  281.     append t "\}\n\n"
  282.     
  283.     append t "# For Tcl 8\n"
  284.     append t "namespace eval $modeAssistant(name) {}\n\n"
  285.     
  286.     if {[string length $modeAssistant(menuname)]} {
  287.     append t "# This proc is called every time we turn the menu on.\n"
  288.     append t "# Its main effect is to ensure this code, including the\n"
  289.     append t "# menu definition below, has been loaded.\n"
  290.     append t "proc $modeAssistant(name)Menu {} {}\n"
  291.     append t "# Now we define the menu items.\n"
  292.     append t "Menu -n \$$modeAssistant(name)Menu -p $modeAssistant(name)::menuProc \{\n"
  293.     if {$modeAssistant(switchhelper)} {
  294.         append t "    /S<U<OswitchTo$appName\n"
  295.     }
  296.     if {$modeAssistant(sendtohelper)} {
  297.         append t "    /S<U<OsendWindowTo$appName\n"
  298.     }
  299.     append t "    anotherCommand\n"
  300.     append t "\}\n\n"
  301.     append t "# This procedure is called whenever we select a menu item\n"
  302.     append t "proc $modeAssistant(name)::menuProc \{menu item\} \{\n"
  303.     append t "    switch -- \$item \{\n"
  304.     if {$modeAssistant(switchhelper)} {
  305.         append t "        switchTo$appName \{app::launchFore \$$sigName\}\n"
  306.         append t "        sendWindowTo$appName \{openAndSendFile \$$sigName\}\n"
  307.     }
  308.     append t "        anotherCommand \{ alertnote {another command} \}\n"
  309.     append t "    \}\n"
  310.     append t "\}\n\n"
  311.     }
  312.  
  313.     append t "# Mode preferences settings, which can be edited by the user (with F12)\n\n"
  314.     append t "newPref flag wordWrap $modeAssistant(wordWrap) [list $modeAssistant(name)]\n\n"
  315.     if {[string length $modeAssistant(funcExpr)]} {
  316.     append t "# These are used by the ::parseFuncs procedure when the user clicks on\n"
  317.     append t "# the {} button in a file edited using this mode.  If you need more sophisticated\n"
  318.     append t "# function marking, you need to add a $modeAssistant(name)::parseFuncs proc\n\n"
  319.     append t "newPref flag funcExpr [list $modeAssistant(funcExpr)] [list $modeAssistant(name)]\n"
  320.     append t "newPref flag parseExpr [list $modeAssistant(parseExpr)] [list $modeAssistant(name)]\n\n"
  321.     }
  322.     set comments {}
  323.     if {[string length $modeAssistant(comments)]} {
  324.     lappend comments -e $modeAssistant(comments)
  325.     append t "# Register comment prefix\n"
  326.     append t "set $modeAssistant(name)::commentCharacters(General) [list $modeAssistant(comments)]\n"
  327.     }
  328.     if {[string length $modeAssistant(multicommentprefix)]} {
  329.     append t "# Register multiline comments\n"
  330.     # So this works with Tcl 7.x
  331.     set e [string index $modeAssistant(multicommentprefix) [expr {[string length $modeAssistant(multicommentprefix)] -1}]]
  332.     set multi [list "$modeAssistant(multicommentprefix) " " $e " " $modeAssistant(multicommentsuffix)"]
  333.     append t "set $modeAssistant(name)::commentCharacters(Paragraph) [list $multi]\n"
  334.     lappend comments -b $modeAssistant(multicommentprefix) $modeAssistant(multicommentsuffix)
  335.     } else {
  336.     append t "# Register multiline comments\n"
  337.     set multi [list "$modeAssistant(comments) " "$modeAssistant(comments) " "$modeAssistant(comments) "]
  338.     append t "set $modeAssistant(name)::commentCharacters(Paragraph) [list $multi]\n"
  339.     }
  340.     append t "# List of keywords\n"
  341.     append t "set $modeAssistant(name)KeyWords \{\n"
  342.     append t "    $modeAssistant(keywords)\n"
  343.     append t "\}\n\n"
  344.     append t "# Colour the keywords, comments etc.\n"
  345.     append t "regModeKeywords $comments $modeAssistant(name) \$$modeAssistant(name)KeyWords\n"
  346.     append t "# Discard the list\n"
  347.     append t "unset $modeAssistant(name)KeyWords\n\n"
  348.  
  349.     new -n $modeAssistant(name)Mode.tcl -text $t
  350.     
  351.     global HOME
  352.     saveAs -f [file join $HOME Tcl Modes $modeAssistant(name)Mode.tcl]
  353.     alertnote "Your new mode has been created and saved in Alpha's 'Modes' folder.\
  354.       Next time you quit and restart Alpha, it will notice the extra file, and rebuild\
  355.       the necessary indices so it knows about your mode."
  356. }
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363.  
  364.